export default function EvenEmitter () {
  this._events = {}
}
EvenEmitter.prototype.on = function (eventName, listener) {
  if (!eventName || !listener) { return }
  const events = this._events
  const listeners = events[eventName] = events[eventName] || []
  const listenersWrapped = typeof listener === 'object'
  if (listeners.indexOf(events[eventName]) === -1) {
    listeners.push(listenersWrapped ? listener : {
      listener: listener,
      once: false
    })
  }
  return this
}
EvenEmitter.prototype.addListener = function (eventName, listener) {
  return this.on(eventName, listener)
}
EvenEmitter.prototype.remove = function (eventName, listener) {
  if (!eventName || !listener) { return }
  const events = this._events
  const listeners = events[eventName]
  if (!listeners || !listeners.length || listeners.length === 0) {
    throw Error('eventName is not defined')
  }
  let removeIndex
  for (let i = 0; i < listeners.length;i++) {
    if (listeners[i].listener === listener) {
      removeIndex = i
      break
    }
  }
  listeners.splice(removeIndex, 1)
}
EvenEmitter.prototype.emit = function () {
  const eventName = [...arguments][0]
  const args = [...arguments].slice(1)
  if (!eventName) { return }
  const events = this._events
  const listeners = events[eventName]
  if (!listeners || !listeners.length || listeners.length === 0) {
    throw Error('eventName is not defined')
  }
  for (let i = 0; i < listeners.length; i++) {
    listeners[i].listener.apply(this, args)
    if (listeners[i].once === true) {
      this.remove(eventName, listeners[i].listener)
    }
  }
}
EvenEmitter.prototype.once = function (eventName, listener) {
  return this.on(eventName, {
    listener: listener,
    once: true
  })
}
EvenEmitter.prototype.allOff = function (eventName) {
  let events = this._events
  let listeners = events[eventName]
  eventName && listeners ? listeners = [] : events = []
  return this
}
EvenEmitter.VISION = '0.0.1'
